﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Windows.Forms;
using ZhCun.CodeBuilder.Builders;

namespace ZhCun.DbCore.CodeBuilder
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
        }
        private bool IsConfigChanged = false;
        /// <summary>
        /// 生成器
        /// </summary>
        private BaseBuilder _BuildCode;

        /// <summary>
        /// 保存代码到文件
        /// </summary>
        /// <param name="codeStr">代码字符串</param>
        private void SaveCodeToFile(string codeStr, string fileName)
        {
            if (string.IsNullOrEmpty(codeStr))
            {
                MessageBox.Show("代码为空!", "保存提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            using (FileStream fs = new FileStream(fileName, FileMode.Create))
            {
                using (StreamWriter sw = new StreamWriter(fs))
                {
                    sw.Write(codeStr);
                }
            }
        }
        /// <summary>
        /// 创建生成器
        /// </summary>
        private BaseBuilder CreateBuilder()
        {
            string connectStr = txtConnectStr.Text;
            BaseBuilder builder;
            string dbType = txtDatabaseType.Text;
            switch (dbType.ToUpper())
            {
                case "SQLSERVER":
                    builder = BuilderFactory.CreateSqlServerBilder(connectStr);
                    break;
                case "MYSQL":
                    builder = BuilderFactory.CreateMySql(connectStr);
                    break;
                case "SQLITE":
                    builder = BuilderFactory.CreateSQLiteBilder(connectStr);
                    break;
                case "OLEDB":
                    builder = BuilderFactory.CreateOleDb(connectStr);
                    break;
                case "ORACLE":
                    builder = BuilderFactory.CreateOracle(connectStr);
                    break;
                default:
                    throw new Exception("不支持的数据库类型,或未配置数据库类型");
            }
            return builder;
        }
        private void FrmMain_Load(object sender, EventArgs e)
        {
            txtConnectStr.Text = ConfigurationManager.AppSettings["ConnectStr"];
            txtNameSpace.Text = ConfigurationManager.AppSettings["AppNamespace"];
            txtSavePath.Text = ConfigurationManager.AppSettings["SavePath"];
            txtDatabaseType.Text = ConfigurationManager.AppSettings["DatabaseType"];
            IsConfigChanged = false;
        }
        private void BtnConnect_Click(object sender, EventArgs e)
        {
            try
            {
                if (_BuildCode != null)
                {
                    if (MessageBox.Show("当前连接已经建立,确定要重新连接吗?", "重新连接确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) != System.Windows.Forms.DialogResult.OK)
                    {
                        return;
                    }
                }
                _BuildCode = CreateBuilder();
                BtnRefreshTable_Click(sender, e);
                BtnRefreshProc_Click(sender, e);

                btnRefreshTable.Enabled = true;
                btnBuildCode.Enabled = true;
                btnSaveAllFile.Enabled = true;
                btnSaveFile.Enabled = true;
                btnRefreshProc.Enabled = true;
                btnBuildProcCode.Enabled = true;
                btnSaveProcFile.Enabled = true;
                btnSaveProcAllFile.Enabled = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show("连接异常,\r\n" + ex.Message);
            }
        }
        private void BtnRefreshTable_Click(object sender, EventArgs e)
        {
            List<string> tableNameList = _BuildCode.GetTableNameList();
            coBoxTable.Items.Clear();
            foreach (string tableName in tableNameList)
            {
                coBoxTable.Items.Add(tableName);
            }
            if (coBoxTable.Items.Count > 0)
                coBoxTable.SelectedIndex = 0;
        }
        private void BtnBuildCode_Click(object sender, EventArgs e)
        {
            txtCode.Text = _BuildCode.GetModelCode(coBoxTable.Text, txtNameSpace.Text);
        }
        /// <summary>
        /// 保存单个类文件
        /// </summary>
        void SaveCodeFileDialog(string tbName, string fileContent)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "*.cs|*.cs";
            sfd.FileName = tbName + ".cs";
            sfd.InitialDirectory = txtSavePath.Text;
            if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                SaveCodeToFile(fileContent, sfd.FileName);
                MessageBox.Show("保存成功!");
            }
        }
        void SaveAllFileDialog(List<string> tbNames, Func<string, string> GetCode)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            fbd.SelectedPath = txtSavePath.Text;
            fbd.ShowNewFolderButton = true;
            if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                string filePath = fbd.SelectedPath;
                foreach (var tableName in tbNames)
                {
                    string fileName = filePath + "\\" + tableName + ".cs"; ;
                    string code = GetCode(tableName);
                    SaveCodeToFile(code, fileName);
                }
                MessageBox.Show("保存成功!");
            }
        }

        private void BtnSaveFile_Click(object sender, EventArgs e)
        {
            string tableName = coBoxTable.Text;
            string fileName = coBoxTable.Text;
            string code = _BuildCode.GetModelCode(tableName, txtNameSpace.Text);
            SaveCodeFileDialog(fileName, code);
        }
        private void BtnSaveAllFile_Click(object sender, EventArgs e)
        {
            List<string> tbNames = new List<string>();
            for (int i = 0; i < coBoxTable.Items.Count; i++)
            {
                string tableName = coBoxTable.Items[i].ToString();
                tbNames.Add(coBoxTable.Items[i].ToString());
            }
            SaveAllFileDialog(tbNames, (tbName) =>
            {
                string code = _BuildCode.GetModelCode(tbName, txtNameSpace.Text);
                return code;
            });
        }

        private void BtnRefreshProc_Click(object sender, EventArgs e)
        {
            List<string> procList = _BuildCode.GetProceduresList();
            coBoxProc.Items.Clear();
            if (procList != null)
            {
                foreach (string procName in procList)
                {
                    coBoxProc.Items.Add(procName);
                }
                if (coBoxProc.Items.Count > 0)
                    coBoxProc.SelectedIndex = 0;
            }
        }

        private void BtnBuildProcCode_Click(object sender, EventArgs e)
        {
            string code = _BuildCode.GetProcModelCode(coBoxProc.Text, txtNameSpace.Text);
            txtCode.Text = code;
        }

        private void BtnSaveProcFile_Click(object sender, EventArgs e)
        {
            string tbName = coBoxProc.Text;
            string code = _BuildCode.GetProcModelCode(tbName, txtNameSpace.Text);
            SaveCodeFileDialog(tbName, code);
        }

        private void BtnSaveProcAllFile_Click(object sender, EventArgs e)
        {
            List<string> procNames = new List<string>();
            foreach (string procName in coBoxProc.Items)
            {
                procNames.Add(procName);
            }
            SaveAllFileDialog(procNames, (procName) =>
            {
                string code = _BuildCode.GetProcModelCode(procName, txtNameSpace.Text);
                return code;
            });
        }

        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (IsConfigChanged && MessageBox.Show("当前配置发生变化是否要保存修改？", "保存确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.OK)
            {
                Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                config.AppSettings.Settings.Remove("ConnectStr");
                config.AppSettings.Settings.Remove("DatabaseType");
                config.AppSettings.Settings.Remove("AppNamespace");
                config.AppSettings.Settings.Remove("DefaultPath");

                config.AppSettings.Settings.Add("ConnectStr", txtConnectStr.Text);
                config.AppSettings.Settings.Add("DatabaseType", txtDatabaseType.Text);
                config.AppSettings.Settings.Add("AppNamespace", txtNameSpace.Text);
                config.AppSettings.Settings.Add("DefaultPath", txtSavePath.Text);

                config.Save(ConfigurationSaveMode.Modified);
            }
        }

        private void Config_TextChanged(object sender, EventArgs e)
        {
            IsConfigChanged = true;
        }
    }
}